﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Threading;
using System.Reflection.Emit;
using System.Diagnostics;

namespace EmitMethodSample
{

    class Program
    {
        static void Main(string[] args)
        {


            ////Sample assembly.
            //// Defines the name of the assembly
            //AssemblyName asmName = new AssemblyName("MyAssembly"); 
            ////Get AppDomain where the assembly needs to be created.
            //AppDomain currentDomain = Thread.GetDomain();

            ////AssemblyBuilder object can be defined from AppDomain needed to build a dynamic assembly. RunAndSave will let you run the application as well as save it to custom dll file
            //AssemblyBuilder builder = currentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);

            ////Every assembly have modules which logically defines the Types. Mymodule is the name of the Module
            //ModuleBuilder mbuilder = builder.DefineDynamicModule("MyModule");

            ////Type Builder can generate a Type. Public class MyClass type is declared
            //TypeBuilder tbuilder = mbuilder.DefineType("MyClass", TypeAttributes.Public);

            ////MethodBuilder builds a method sum for the Type tbuilder which takes two int argument and returns float32
            //Type[] tparams = { typeof(System.Int32), typeof(System.Int32) };
            //MethodBuilder methodSum = tbuilder.DefineMethod("sum", MethodAttributes.Public, typeof(System.Int32), tparams);


            ////ILGenerator is used to Emit IL for the method.
            //ILGenerator generator = methodSum.GetILGenerator();

            //generator.DeclareLocal(typeof(System.Single));  //Declares a local variable to the method
            //generator.Emit(OpCodes.Ldarg_1);    // Loads 1st argument passed to the method
            //generator.Emit(OpCodes.Ldarg_2);    // Loads 2nd argument passed to the method
            //generator.Emit(OpCodes.Add_Ovf);    // adds the two numbers loaded.
            //generator.Emit(OpCodes.Conv_R4);    // Converts the result to float32
            //generator.Emit(OpCodes.Stloc_0);    // Stores it back to local variable.. You can omit this and next line if you wish
          
            //generator.Emit(OpCodes.Ldloc_0);    // Loads the local float32 variable again into memory.
            //generator.Emit(OpCodes.Ret);        //Returns the loaded value back to the external environment

            ////Create the Type MyClass in the Assembly
            //Type thistype = tbuilder.CreateType();

            ////builder.Save("myassembly.dll");  // You name the assembly to save the dll
            //MethodInfo info = thistype.GetMethod("sum", BindingFlags.Instance | BindingFlags.Public);
            //object thisObj = Activator.CreateInstance(thistype);

            //object result = info.Invoke(thisObj, BindingFlags.Public | BindingFlags.CreateInstance, null, new object[] {10,20}, Thread.CurrentThread.CurrentCulture);

            
            //Console.WriteLine("Sum of 10, 20 : {0}", result);


            DynamicBuilder dd = new DynamicBuilder();
            dd.CreateBuilder();
             Console.ReadLine();
        }
    }
}

